Skip to content

[NV] feat(minimaxm3): add B200 disaggregated configs / [NV] feat(minimaxm3):新增 B200 分离式配置 - #2230

Open
xinli-sw wants to merge 17 commits into
mainfrom
feat/minimaxm3-b200-vllm-disagg
Open

[NV] feat(minimaxm3): add B200 disaggregated configs / [NV] feat(minimaxm3):新增 B200 分离式配置#2230
xinli-sw wants to merge 17 commits into
mainfrom
feat/minimaxm3-b200-vllm-disagg

Conversation

@xinli-sw

@xinli-sw xinli-sw commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add the minimaxm3-fp4-b200-dynamo-vllm config for nvidia/MiniMax-M3-NVFP4 on NVIDIA B200 with FP4 precision.
  • Add six multi-node, disaggregated Dynamo-vLLM srt-slurm recipes for ISL 8192 / OSL 1024. The topology matrix uses 1-4 prefill workers with TP2/EP2/data-parallel attention and 1-2 decode workers with TP4, covering concurrency 1 through 1024.
  • Route the new config through runners/launch_b200-dgxc.sh and pin vllm/vllm-openai:nightly-4080263bb2c5d10deac17aaeb88e0823bc35bca9 with Dynamo 1.3.0.dev20260710.
  • Scope: disaggregated multi-node only; no AgentX workload and no speculative decoding.

Validation

  • Run Sweep https://github.com/SemiAnalysisAI/InferenceX/actions/runs/30118047286 completed successfully on in-PR commit 6ebf4ac with six multi-node 8k1k benchmark jobs, six multi-node eval jobs, collect-evals, collect-results, and compare-results all passing.
  • The gsm8k em_strict scores range from 0.9484 to 0.9530 across the six evaluated topologies, above the 0.90 default threshold.
  • Current head 3f245da only corrects the image string in perf-changelog.yaml and is marked [skip-sweep]. Its red check-changelog result is limited to append-only perf-changelog.yaml drift against newer main and requires routine changelog synchronization before merge.

中文说明

  • 新增 minimaxm3-fp4-b200-dynamo-vllm 配置,在 NVIDIA B200 上以 FP4 精度运行 nvidia/MiniMax-M3-NVFP4。
  • 新增 6 个多节点 Dynamo-vLLM 分离式推理 srt-slurm 配方,输入序列长度(ISL)为 8192、输出序列长度(OSL)为 1024。拓扑矩阵包含 1-4 个预填充 worker(TP2/EP2/数据并行注意力)和 1-2 个解码 worker(TP4),覆盖并发 1 到 1024。
  • 通过 runners/launch_b200-dgxc.sh 路由新配置,并固定使用 vllm/vllm-openai:nightly-4080263bb2c5d10deac17aaeb88e0823bc35bca9 镜像和 Dynamo 1.3.0.dev20260710。
  • 范围仅包含多节点分离式推理;不包含 AgentX 工作负载,也不使用投机解码。

验证

  • Run Sweep https://github.com/SemiAnalysisAI/InferenceX/actions/runs/30118047286 在本 PR 仍包含的提交 6ebf4ac 上成功完成;6 个多节点 8k1k 基准测试 job、6 个多节点评估 job,以及 collect-evals、collect-results 和 compare-results 均通过。
  • 6 个已评估拓扑的 gsm8k em_strict 得分为 0.9484-0.9530,高于默认阈值 0.90。
  • 当前 head 3f245da 仅修正 perf-changelog.yaml 中的镜像字符串,并带有 [skip-sweep] 标记。当前 check-changelog 的红灯仅由分支与较新 main 之间的 perf-changelog.yaml 仅追加式漂移引起,合并前需要执行常规变更日志同步。

Comment on lines +2 to +5
slurm:
account: coreai_comparch_inferencex
partition: batch
time_limit: "01:00:00"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 All four new B200 minimax-m3 recipes set slurm.time_limit: "01:00:00", well below the launcher's 4h default and the 3-8h used elsewhere in the tree, and none define a health_check block, so the launcher's sed that bumps max_attempts 360→720 (meant to absorb cold-cache loads off shared FS) is a no-op here. The model loads from shared scratch FS, so a slow cold load could eat the 1h walltime and kill the job in TIMEOUT with no results — worth double-checking against the sibling B300 recipes (no time_limit override, health_check present) before merge.

Extended reasoning...

The bug: all four new recipes (2p2d-c128, 3p2d-c256, 3p2d-c512, 4p2d-c1024) set slurm.time_limit: "01:00:00". This overrides the generated srtslurm.yaml's default_time_limit: "4:00:00" (set in runners/launch_b200-dgxc.sh) downward to a quarter of that. Across the whole srt-slurm-recipes tree, the only other explicit time_limit values used are 3h and 8h — 1h is an outlier by a wide margin, and it's the only class of minimax-m3 recipe that sets it this low.\n\nWhy the launcher's usual safety net doesn't apply: runners/launch_b200-dgxc.sh has a sed step specifically to absorb slow cold-cache model loads off shared FS:\n\nThis only works if the recipe already has a health_check.max_attempts line to rewrite (going from 360×10s=3600s to 720×10s=7200s). None of the four new recipes define a health_check section at all, so this sed matches nothing and is a silent no-op. Compare to the sibling B300-fp4 minimax-m3 recipes (same checkpoint, same container image), which set no slurm.time_limit override (inheriting the 4h default) and still carry health_check.max_attempts: 360, letting the sed extend their health-check budget to 2h. The new B200 recipes get neither protection.\n\nWhy this matters here specifically: MODEL_PATH for minimaxm3+fp4 resolves to /scratch/fsw/models/MiniMax-M3-NVFP4, shared scratch FS — the same class of cold-cache-slow-load risk that motivated both the sed and the 8h time_limit/1440 max_attempts used by the sibling deepseek-v4 disagg recipes (comment there: "to absorb cold-cache model loads"). If a cold cache causes a slow multi-worker MoE weight load (the 4p2d/c1024 config spans 4 nodes and has the most startup coordination), the health-check window and remaining walltime could both be exhausted before srtctl ever runs the benchmark sweep, and SLURM kills the job in TIMEOUT — a multi-node B200 allocation consumed with zero results collected, which is a much worse failure mode than a clean error.\n\nProof sketch: launch job → sed looks for ^ max_attempts: [0-9]* in the recipe, finds no match (none of the 4 files have a health_check key), no-op → srtctl applies the recipe with its default health-check window (360×10s=3600s=1h) → model load from /scratch/fsw/models/MiniMax-M3-NVFP4 under cold cache takes long enough to approach that 1h health-check budget → SLURM's own 1h wall-clock limit (time_limit: "01:00:00") expires around the same time the load might still be settling → job terminates in TIMEOUT before the benchmark concurrency point runs → no results_concurrency_*.json produced, wasted allocation.\n\nCounterpoint worth weighing: a reviewer flagged that each of these recipes runs a single concurrency point (skip_initial_test: true, one value in concurrencies) rather than a multi-point sweep like the B300 sibling that relies on the 4h default, and that MiniMax-M3-NVFP4 is a much smaller 4-bit checkpoint than the ~680GB DSR1-FP8 case the sed comment references — so 1h may be a deliberate, proportionately-sized choice rather than an oversight, and the perf-changelog even labels these "validated" configurations. That's plausible, but it doesn't fully explain why these are the only minimax-m3 recipes with no health_check block at all (even the B300 siblings running fewer/no sweep points keep one), and a single occurrence of cold cache during CI reruns would still zero out the run. Given the WIP status and that this is easy to align with the siblings, it's worth a second look before merge.\n\nFix: either drop the slurm.time_limit override (inherit the 4h default like the B300 siblings) or add a health_check block (e.g. max_attempts: 360) so the launcher's sed can extend it, matching the pattern used everywhere else in the tree.

Comment thread runners/launch_b200-dgxc.sh
@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

@xinli-sw
xinli-sw force-pushed the feat/minimaxm3-b200-vllm-disagg branch from 64eef80 to 2ada754 Compare July 16, 2026 04:22
@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

2 similar comments
@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

@xinli-sw
xinli-sw force-pushed the feat/minimaxm3-b200-vllm-disagg branch from f0a7050 to 47f6115 Compare July 18, 2026 15:48
@github-actions

Copy link
Copy Markdown
Contributor

@xinli-sw
xinli-sw force-pushed the feat/minimaxm3-b200-vllm-disagg branch from 47f6115 to dab5d91 Compare July 18, 2026 18:35
@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

1 similar comment
@github-actions

Copy link
Copy Markdown
Contributor

@xinli-sw
xinli-sw force-pushed the feat/minimaxm3-b200-vllm-disagg branch 2 times, most recently from 288eccd to 845cee3 Compare July 19, 2026 04:37
@github-actions

Copy link
Copy Markdown
Contributor

@xinli-sw
xinli-sw force-pushed the feat/minimaxm3-b200-vllm-disagg branch from 845cee3 to 9c33842 Compare July 19, 2026 14:11
@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

xinli-sw added 2 commits July 23, 2026 19:21
…B200/B300 disagg configs

- Merge origin/main (resolve perf-changelog.yaml conflict by keeping both entries)
- Bump container image to vllm/vllm-openai:nightly-4080263bb2c5d10deac17aaeb88e0823bc35bca9
  across all 12 branch-specific minimax-m3 YAML configs
- Replace UCX_TLS with UCX_TCP_AF_PRIO=inet; remove UCX_IB_ROCE_REACHABILITY_MODE
  in both prefill_environment and decode_environment of each config
@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

@xinli-sw xinli-sw changed the title [WIP] feat(minimaxm3): add B200 disaggregated configs [NV] feat(minimaxm3): add B200 disaggregated configs Jul 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

@xinli-sw

Copy link
Copy Markdown
Collaborator Author

/reuse-sweep-run

@Ankur-singh

Copy link
Copy Markdown
Collaborator

/reuse-sweep-run 30118047286

…skip-sweep]

The config and all six b200-fp4 recipes pin
vllm/vllm-openai:nightly-4080263bb2c5d10deac17aaeb88e0823bc35bca9, but the
changelog entry still cited the pre-bump cu129-nightly-8e981630c9 tag.
Documentation-only fix; no benchmark or config behavior changes.
@Ankur-singh

Copy link
Copy Markdown
Collaborator

As a PR reviewer and CODEOWNER, I have reviewed this and have:

  • Verified that as of the moment of typing this, this is the latest version of PR_REVIEW_CHECKLIST.md
  • Verified that the general code quality meets the InferenceX standard and does not make the code quality any worse.
  • Verified that this PR has passed PR validation. Please link to GitHub Action workflow that shows this. — https://github.com/SemiAnalysisAI/InferenceX/actions/runs/30118047286
  • Verified that this PR passes evals. Please link to GitHub Action workflow that shows this. — https://github.com/SemiAnalysisAI/InferenceX/actions/runs/30118047286
  • Verified that speculative decoding PRs uses chat templates to align the AL distribution to real world
  • For agentic workloads: verified that speculative-decoding configs (EAGLE / MTP / draft models) run with simulated synthetic acceptance, with the acceptance-length value taken from the committed golden AL curve in golden_al_distribution/ for that model, thinking mode, and draft length. A submission may choose any supported draft length, but it may not substitute a different acceptance target.
  • Verified that the model architecture isn't changed with benchmark hacks like using --hf-overrides to skipping indexer for every x layers on models that don't natively support this. As a general rule, we won't accept optimizations that reduces the number of model architecture FLOPs. Anything that makes that same computation run faster is fair game; FLOPs at lower precisions is fine, given that the config passes private evals. As an general north star princple, we should only use optimizations which is used in production by customers that care about accuracy
  • If an company claims that they support vLLM/SGLang as first class LLM inference engines on their hardware, I have verified that the respective vLLM submission made using upstream https://hub.docker.com/u/vllm docker repo, upstream SGLang https://hub.docker.com/u/lmsysorg docker repo. The only exceptions are for new hardware, such as MI455X UALoE72, Vera Rubin NVL72, Rubin NVL8, etc., and for new model architectures where there is an actual reason why vLLM/SGLang does not fundamentally support them yet as supported by vLLM/SGLang community maintainers
  • If an company claims that they support vLLM/SGLang as first class upstream in-tree LLM inference engines on their hardware, I have have verified that the respective vLLM/SGLang submission has been made before additional frameworks (TRT-LLM, ATOM, etc.). The only exceptions are for new hardware, such as MI455X UALoE72, Vera Rubin NVL72, Rubin NVL8, etc., and for new model architectures where there is an actual reason why vLLM/SGLang does not fundamentally support them yet.
  • Verified that every single-node vLLM/SGLang recipe in this PR is documented in the official vLLM recipes and/or the SGLang cookbook:
    • I linked the corresponding upstream PR in the vLLM recipe repo or SGLang repo and verified that it is MERGED before this InferenceX PR merges. An opened, draft, or closed-without-merge upstream PR does not satisfy this requirement. If the matching recipe was already published, I linked the published recipe/cookbook page in the additional detail section below.
  • Verified that this PR does not patch the inference engine or serving stack — the pinned image must run as shipped. This covers .patch files / git apply / patch, inline patches embedded in benchmark scripts (e.g. a python3/sed heredoc that rewrites installed engine sources before serving), in-place edits of site-packages, monkey-patching, overwriting container files, and installing forked/rebuilt engine wheels on top of the pinned image. The only exception is a patch covered by a filled-out waiver at docs/waiver/<PR_NUMBER>.md — named after the PR that introduces the patch and filed in that same PR, stating what is patched, why the unmodified upstream image cannot run this benchmark, the upstream PR/issue link, and the removal plan — which I have linked below in the additional detail section.
  • If any of the above criteria cannot reasonably be satisfied, I have provided additional reasoning below.

Additional detail section:

  • Scope: one new config key minimaxm3-fp4-b200-dynamo-vllm — MiniMax-M3 NVFP4, B200, disaggregated multi-node Dynamo-vLLM at 8k/1k, concurrencies 1–1024 across six new srt-slurm recipes, plus a runners/launch_b200-dgxc.sh routing branch for dynamo-vllm + minimaxm3 + fp4. Non-speculative (spec-none).
  • Validation & evals: Run Sweep https://github.com/SemiAnalysisAI/InferenceX/actions/runs/30118047286 (commit 6ebf4aca15d6e5a1240ebb1e90fda8feb88904e9, which remains in this PR's commit list) is green with six non-skipped multi-node 8k1k benchmark jobs and six non-skipped multi-node eval jobs; collect-evals/collect-results/compare-results all succeeded.
  • Eval accuracy (verified, not just green): gsm8k em_strict = 0.9484, 0.9522, 0.9484, 0.9530, 0.9500, 0.9515 (n=1319 each, se ≈ 0.006) across the six evaluated points, against the utils/evals/thresholds.yaml bar of 0.90 (task default; no minimaxm3 override) — roughly a 5-point margin. The run's "Verify eval scores" step executed and passed, and the evals ran on the same image the config pins.
  • Upstream image consistency: the master-config entry and all six recipes pin vllm/vllm-openai:nightly-4080263bb2c5d10deac17aaeb88e0823bc35bca9 (upstream vLLM Docker Hub org), matching the image recorded in every benchmark and eval job name.
  • Engine-first ordering: a plain-vLLM entry for this model+SKU (minimaxm3-fp4-b200-vllm) already exists in configs/nvidia-master.yaml, so the Dynamo-vLLM entry does not precede a vLLM submission.
  • No engine patching: the recipes are declarative srt-slurm YAML and the launcher change only clones NVIDIA/srt-slurm and copies these recipes into it (orchestration). No .patch/git apply, no sed -i on engine sources, no site-packages edits, no forked engine wheels; the pinned image runs as shipped.
  • Changelog correction (by me, this review): commit 3f245da fixes the changelog entry's image string, which still cited the pre-bump cu129-nightly-8e981630c9… tag while the config and all six recipes pin nightly-4080263bb2…. Documentation-only, tagged [skip-sweep]; no benchmark, config, or measurement behavior changed.
  • Known follow-up — check-changelog is red for an unrelated reason: utils/process_changelog.py runs a two-dot git diff main <head> and rejects any deletion, so this branch now reports the four lines of PR dsr1-fp8-b300-sglang-mtp: bump SGLang image to v0.5.15.post1-cu130 #2313's entry (merged into main after this branch last synced) as deletions. This drift is pre-existing and independent of my correction — commit 6ebf4aca shows the same four deletions against current main. It is resolved by the routine changelog re-sync (main's full entry list with this branch's entry re-appended last) before merge, and does not affect the benchmark or eval evidence above.
  • Speculative-decoding items (unchecked): not applicable — this configuration runs no speculative decoding (every benchmark and eval job reports spec-none), so neither the chat-template AL attestation nor the agentic golden-AL simulation applies.
  • Recipe items (both left unchecked — upstream documentation is not yet complete for this configuration):
    • Published recipe: https://recipes.vllm.ai/MiniMaxAI/MiniMax-M3 (source: models/MiniMaxAI/MiniMax-M3.yaml). It already documents the nvfp4 variant (model_id: nvidia/MiniMax-M3-NVFP4 — the exact model here), pd_cluster in compatible_strategies (rendered as "Prefill/Decode Disaggregation"), b200: verified hardware, --kv-cache-dtype fp8, --block-size 128, --language-model-only, --enable-expert-parallel, --trust-remote-code, and VLLM_FLOAT32_MATMUL_PRECISION: high.
    • What is still missing upstream: the published recipe does not yet carry the main-model attention configuration this PR runs — attention-config {"backend": "FLASHINFER", "use_trtllm_attention": true, "indexer_kv_dtype": "fp8"}. (Upstream's only FLASHINFER reference is --mm-encoder-attn-backend, which configures the vision encoder, a different component.) These are kernel-selection / KV-cache-dtype args, so I am treating them as recipe-defining rather than harness tuning, and I am not claiming the recipe attestation is satisfied.
    • In-flight upstream work: vllm-project/recipes#682 (maintainer faradawn) adds --attention_config.indexer_kv_dtype fp8 to the nvfp4 variant plus an EAGLE3-GQA mode for pd_cluster serving. It is open, not merged. I asked there for the remaining two keys (backend: FLASHINFER, use_trtllm_attention: true) to be folded in: Minimax M3 agg vllm-project/recipes#682 (comment). No duplicate PR was opened, since that PR already owns this file and variant.
    • Effect on merge: this sign-off covers the benchmark and eval evidence; it does not assert upstream recipe completeness. If the recipe requirement is enforced for this disaggregated submission, #682 (with the two additional keys) should merge before this PR does.
    • InferenceX-specific settings that are expected to differ from any recipe and are not part of the above gap: kv_role: kv_both worker colocation, per-lane concurrency/worker counts, stream-interval, max-cudagraph-capture-size, and no-enable-flashinfer-autotune.

Signed: Ankur-singh

@Klaud-Cold

Copy link
Copy Markdown
Collaborator

✅✅✅ Verdict: PASS ✅✅✅

✅ Check 0 (CODEOWNER): PASS — Ankur-singh is a named owner of configs/nvidia-master.yaml; all other changed paths fall only to the catch-all, which any recognized CODEOWNER satisfies.
✅ Check 1 (sweep on in-PR commit): PASS — commit 6ebf4ac (still in this PR) carries six non-skipped green multi-node 8k1k / and six multi-node eval / check-runs from run 30118047286 (this is a multi-node config, so those are the executed per-config jobs).
✅ Check 2 (eval accuracy): PASS — downloaded agg_eval_all.json from that run: gsm8k em_strict 0.9484–0.9530 (n=1319) across all six evaluated points vs the 0.90 default bar (no minimaxm3 override in utils/evals/thresholds.yaml); run used the PR-pinned image vllm/vllm-openai:nightly-4080263b….
➖ Check 3 (recipe linked & merged): N/A — disaggregated/multi-node submission (all benchmark files under benchmarks/multi_node/**, entry has multinode: true + disagg: true, framework dynamo-vllm); the recipe-link requirement applies to single-node recipes only.
✅ Check 4 (reuse command): PASS — /reuse-sweep-run 30118047286 posted by COLLABORATOR Ankur-singh (plus a bare /reuse-sweep-run from COLLABORATOR xinli-sw).
✅ Check 5 (latest template): PASS — sign-off matches the current docs/PR_REVIEW_CHECKLIST.md item-for-item; the four unchecked items (spec-decode ×2, recipe ×2) are each explained in the additional detail section.
✅ Check 6 (upstream image / engine-first): PASS — image is from the upstream vllm/ Docker Hub org, and vLLM entry minimaxm3-fp4-b200-vllm (B200) already exists in configs/nvidia-master.yaml, so the Dynamo-vLLM entry does not precede a vLLM submission.
✅ Check 7 (no architecture hacks): PASS — no --hf-overrides/model-config edits in the diff; language-model-only only skips the vision encoder, which this text-only benchmark never exercises, and appears in the published upstream recipe; fp8 kv/indexer dtype is lower-precision compute backed by passing evals.
➖ Check 8 (spec-decode chat template): N/A — no speculative decoding (all jobs spec-none).
✅ Check 9 (no engine patches): PASS — recipes are declarative srt-slurm YAML; the launcher change only clones NVIDIA/srt-slurm and copies these recipes into it; the pinned image runs as shipped.
➖ Check 10 (agentic golden AL): N/A — no agentic speculative-decoding changes.

@Ankur-singh Ankur-singh changed the title [NV] feat(minimaxm3): add B200 disaggregated configs [NV] feat(minimaxm3): add B200 disaggregated configs / [NV] feat(minimaxm3):新增 B200 分离式配置 Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants